import os
import threading
import random
from datetime import datetime
import itertools
from src.database.dao_factory import DAOFactory
from src.modules.whoosh_processor import WhooshProcessor
from src.utils.util import Util
from src.utils.logger import log_info, log_error, log_warning

class MergeController:
    def __init__(self):
        self.running = False
        self.thread = None
        self.log_messages = []
        self.status = "idle"
        self.whoosh_processor = WhooshProcessor()
        self.output_files = []
        self.failed_categories = []
        self.dao_factory = DAOFactory.get_instance()

    def process_merge(self, prompt_data, output_folder, settings, date_range,
                      transition_effect,
                      audio_ids=[]):
        if self.running:
        # 不再简单返回失败信息，而是返回当前任务的状态和参数
            return {
                "success": True, 
                "resumed": True,  # 标记这是恢复的任务，不是新任务
                "message": "已恢复正在运行的任务",
                "status": self.status,
                "logs": self.log_messages,
                "output_files": self.output_files,
                "params": {
                    "output_folder": self.output_folder,
                    "settings": self.settings,
                    "prompt_count": len(self.prompt_data) if hasattr(self, 'prompt_data') else 0,
                    "has_audio": len(self.audio_ids) > 0,
                    "transition_effect": self.transition_effect, 
                }
            }            
        if not os.path.exists(output_folder):
            os.makedirs(output_folder, exist_ok=True)
            
        # 清空文件记录
        self.output_files = []
        
        # 保存参数
        self.prompt_data = prompt_data
        self.output_folder = output_folder
        self.settings = settings
        self.date_range = date_range
        self.audio_ids = audio_ids  # 保存音频路径
        self.transition_effect = transition_effect
        
        # 保存配置到数据库
        try:
            self.config = self.dao_factory.get_video_generation_config_dao().create(
                name=f"Generation {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
                prompt_data=prompt_data,
                date_range=date_range,
                transition_effect=settings.get('transition_effect', 'fade'),
                transition_duration=float(settings.get('transition_duration', 1.0)),
                remove_voice=settings.get('remove_voice', False),
                random_limit=settings.get('random_limit', 3),
                generate_all=settings.get('generate_all', False)
            )
            self._log(f"已保存生成配置，ID: {self.config.id}")
        except Exception as e:
            log_error(f"保存视频生成配置失败: {e}")
            self._log(f"保存视频生成配置失败: {e}", level="error")
            self.config = None
            
        # 开始异步处理
        self.running = True
        self.status = "running"
        
        if settings.get('generate_all', False):
            self.thread = threading.Thread(target=self._process_all_combinations)
        else:
            self.thread = threading.Thread(target=self._process_mixing_request)
            
        self.thread.daemon = True
        self.thread.start()
        
        return {"success": True, "message": "开始处理视频混搭"}        

    def _process_mixing_request(self):
        try:
            # 获取日期范围
            start_date, end_date = self._parse_date_range()
            
            # 为每个提示搜索视频
            merge_results = []
            random_limit = self.settings.get('random_limit', 3)
            
            for idx, category, text in self.prompt_data:
                if not self.running:
                    break
                    
                self._log(f"搜索视频: 类别={category}, 关键词={text if text else '(空)'}")
                # 使用whoosh_processor搜索视频
                results = self.whoosh_processor.search(
                    category=category,
                    query_str=text, 
                    start_date=start_date, 
                    end_date=end_date,
                    limit=random_limit  # 搜索更多结果，然后随机选择
                )

                if not results:
                    # 记录失败的类别和关键词
                    self._log(f"未找到匹配的视频: 类别={category}, 关键词={text}", level="error")
                    self.failed_categories.append({
                        "category": category,
                        "keyword": text,
                        "index": idx
                    })
                    # 立即终止处理
                    self.status = "completed"
                    self.running = False
                    return

                # 随机选择视频
                random_selection = random.sample(results, 1)
                for result in random_selection:
                    video_id = result["video_id"]
                    log_info(f"找到视频:", ext=result)
                    if result["category"] == '自定义':
                        # 如果是自定义类别，直接使用视频ID
                        merge_results.append(video_id)
                        self._log(f"已选择自定义视频: 路径={video_id}")
                        continue
                    video = self.dao_factory.get_video_dao().get_by_id(int(video_id))
                    if video and video.local_path:
                        merge_results.append(video.local_path)
                        self._log(f"已选择视频: ID={video_id}, 路径={video.local_path}")

            if not merge_results:
                self._log("没有找到任何匹配的视频", level="warning")
                self.status = "completed"
                self.running = False
                return
                
            # 输出文件路径
            output_filename = f"mixed_{datetime.now().strftime('%Y%m%d_%H%M%S')}.mp4"
            output_path = os.path.join(self.output_folder, output_filename)
            
            self._log(f"开始合并 {len(merge_results)} 个视频...")
            remove_voice = self.settings.get('remove_voice', False)
            
            # 调用合并功能
            merged_videos = Util.merge_videos(*merge_results,
                              output_path=output_path,
                              remove_voice=remove_voice,
                              audio_ids=self.audio_ids,
                              logger=self._log,
                              transition_effect=self.transition_effect,  # 添加过渡效果参数
                              )  # 添加音频路径参数
            
            for merged_video in merged_videos:
                audio_path = merged_video.get("audio", "")
                video = merged_video.get("video", "")
                self.output_files.append({
                    "output_path": video,
                    "type": "video",
                    "name": os.path.basename(video),
                    "audio_name": os.path.basename(audio_path) if audio_path else "",
                })
                self._save_generated_video(
                    file_path=video,
                    source_videos=merge_results,
                    audio_path=audio_path,
                )
                self._log(f"合并完成: {os.path.basename(video)}")

        except Exception as e:
            self._log(f"视频混搭过程中出错: {e}", level="error")
            log_error(f"视频混搭错误: {e}")
        finally:
            self.dao_factory.refresh_session()
            self.status = "completed"
            self.running = False
    
    def _parse_date_range(self):
        # 解析日期范围
        start_date = self.date_range.get('start_date')
        end_date = self.date_range.get('end_date')
        
        # 日期格式处理逻辑...
        return start_date, end_date
        
    def clear_logs(self):
        """
        清空日志记录
        """
        self.log_messages = []
        return {"success": True, "message": "日志已清空"}
        
    def _log(self, message, level="info"):
        if level == "error":
            log_error(message)
        if level == "warning":
            log_warning(message)
        if level == "info":
            log_info(message)
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_entry = {"timestamp": timestamp, "message": message, "level": level}
        self.log_messages.append(log_entry)
        if len(self.log_messages) > 1000:
            self.log_messages = self.log_messages[-1000:]
    
    def get_status(self):
        return {
            "status": self.status,
            "running": self.running,
            "logs": self.log_messages,
            "output_files": self.output_files,
        }
    
    def stop_processing(self):
        if not self.running:
            return {"success": False, "message": "没有正在运行的任务"}
            
        self.running = False
        self._log("正在停止处理...")
        
        # 等待线程结束
        if self.thread and self.thread.is_alive():
            self.thread.join(timeout=2.0)
            
        return {"success": True, "message": "处理已停止"}
    
    # 添加_process_all_combinations方法实现

    def _process_all_combinations(self):
        """
        处理所有可能的视频组合
        """
        try:
            # 存储每个分类/关键词搜索到的视频
            self._log("开始处理所有可能的视频组合")
            video_groups = []
            remove_voice = self.settings.get('remove_voice', False)
            self.failed_categories = []  # 清空失败的类别记录
            
            # 获取日期范围
            start_date, end_date = self._parse_date_range()
            
            for idx, category, text in self.prompt_data:
                # 检查分类是否存在，如果不存在则跳过
                if not category.strip():
                    continue
                    
                search_text = text.strip()
                
                # 准备搜索关键词
                search_keywords = []
                if not search_text:
                    search_keywords = [""]
                else:
                    # 分词处理文本关键词
                    words = [search_text]
                    filtered_words = [w for w in words if w.strip() not in '，。！？、；：''""（）【】《》,.!?;:\'"()[]<>']
                    search_keywords = filtered_words if filtered_words else [""]
                
                # 如果没有额外关键词，使用分类本身作为关键词
                if not search_keywords:
                    search_keywords = [""]
                    
                # 搜索处理
                group_videos = []
                found_videos_for_category = False
                
                for word in search_keywords:
                    self._log(f"搜索视频: 分类={category}, 关键词={word}")
                    search_results = self.whoosh_processor.search(
                        category=category,
                        query_str=word,
                        start_date=start_date,
                        end_date=end_date,
                        limit=self.settings.get("random_limit", 3)  # 增加搜索结果数量，提供更多组合可能性
                    )
                    
                    if search_results:
                        # 将搜索结果添加到组中
                        for result in search_results:
                            video_id = result["video_id"]
                            video = self.dao_factory.get_video_dao().get_by_id(video_id=video_id)
                            if video and video.local_path:
                                group_videos.append(video.local_path)
                                self._log(f"找到视频: {os.path.basename(video.local_path)}")
                                found_videos_for_category = True
                                
                # 检查是否为当前类别找到视频
                if not found_videos_for_category:
                    self._log(f"没有为类别 {category} 找到任何视频", level="error")
                    self.failed_categories.append({
                        "category": category,
                        "keyword": text,
                        "index": idx
                    })
                    # 立即终止处理
                    self.status = "completed"
                    self.running = False
                    return
                
                if group_videos:
                    video_groups.append(group_videos)
                    self._log(f"分类 {category} 找到 {len(group_videos)} 个视频")
            
            # 检查是否有足够的视频组
            if len(video_groups) < 2:
                self._log("没有足够的视频组进行组合，至少需要两个组。")
                self.status = "completed"
                self.running = False
                return
            
            # 从每个组中选择随机视频进行组合
            import itertools
            
            # 生成所有可能的组合
            combinations = list(itertools.product(*video_groups))
            self._log(f"共生成 {len(combinations)} 种组合可能")
            
            # 最多处理10个组合以避免生成过多视频
            max_combinations = len(combinations)
            selected_combinations = combinations[:max_combinations]
            
            for i, combo in enumerate(selected_combinations):
                if not self.running:
                    break
                    
                # 检查组合中是否有重复视频
                if len(set(combo)) != len(combo):
                    self._log(f"跳过组合 {i+1}，因为包含重复视频")
                    continue
                    
                self._log(f"处理组合 {i+1}/{max_combinations}")
                
                # 创建输出文件名
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                output_filename = f"combo_{i+1}_{timestamp}.mp4"
                output_path = os.path.join(self.output_folder, output_filename)
                
                # 合并视频
                self._log(f"开始合并 {len(combo)} 个视频...")
                try:
                    merged_videos = Util.merge_videos(*combo, 
                                      output_path=output_path,
                                      remove_voice=remove_voice,
                                      audio_ids=self.audio_ids,
                                      logger=self._log,
                                      transition_effect=self.transition_effect,  # 添加过渡效果参数
                                      # 添加音频路径参数
                                      )
                    for merged_video in merged_videos:
                        audio_path = merged_video.get("audio", "")
                        video = merged_video.get("video", "")
                        self.output_files.append({
                            "output_path": video,
                            "type": "video",
                            "name": os.path.basename(video),
                            "audio_name": os.path.basename(audio_path) if audio_path else "",
                        })
                        self._save_generated_video(
                            file_path=video,
                            source_videos=list(combo),
                            audio_path=audio_path,
                            combination_number=i + 1
                        )
                        self._log(f"合并完成: {os.path.basename(video)}")
                except Exception as e:
                    self._log(f"视频混搭失败: {e}", level="error")
            
            self._log("所有组合处理完成")
            
        except Exception as e:
            self._log(f"视频混搭过程中出错: {e}", level="error")
            log_error(f"视频混搭错误: {e}")
        finally:
            self.dao_factory.refresh_session()
            self.status = "completed"
            self.running = False
            
    def upload_audio(self, audio_file, group_id, order, subtitle_file=None, target_directory=None, meta_data=None):
        """
        上传音频文件到指定目录
        
        :param audio_file: 上传的音频文件对象
        :param group_id: 分组ID
        :param order: 排序值
        :param subtitle_file: 上传的字幕文件对象（可选）
        :param target_directory: 目标目录，如果为None则使用默认目录
        :param meta_data: 额外元数据
        :return: 处理结果
        """
        if audio_file is None:
            return {"success": False, "message": "没有提供文件"}
        
        try:
            # 获取原始文件名并确保安全
            original_filename = audio_file.filename
            # 移除可能的路径注入字符
            safe_filename = os.path.basename(original_filename)
            
            # 如果未指定目标目录，使用系统默认目录
            if not target_directory:
                from src.config import AUDIO_DIR
                target_directory = AUDIO_DIR
            
            if not meta_data:
                meta_data = {}
            
            # 确保目录存在
            if not os.path.exists(target_directory):
                os.makedirs(target_directory, exist_ok=True)
                
            # 生成带时间戳的文件名，避免重名
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename, ext = os.path.splitext(safe_filename)
            new_filename = f"{filename}_{timestamp}{ext}"
            audio_path = os.path.join(target_directory, new_filename)
            
            # 保存音频文件
            audio_file.save(audio_path)
            
            # 处理字幕文件（如有）
            subtitle_path = None
            if subtitle_file:
                subtitle_filename = os.path.basename(subtitle_file.filename)
                subtitle_name, subtitle_ext = os.path.splitext(subtitle_filename)
                new_subtitle_name = f"{subtitle_name}_{timestamp}{subtitle_ext}"
                subtitle_path = os.path.join(target_directory, new_subtitle_name)
                subtitle_file.save(subtitle_path)
            
            # 使用新的DAO创建记录
            result = self.dao_factory.get_uploaded_file_dao().create_audio_with_subtitle(
                audio_path=audio_path,
                audio_filename=new_filename,
                subtitle_path=subtitle_path,
                subtitle_filename=new_subtitle_name if subtitle_file else None,
                group_id=group_id,
                order=order,
                meta_data=meta_data,
                status="active"
            )
            
            if not result.get("success", False):
                raise Exception(result.get("message", "创建文件记录失败"))
            
            self._log(f"音频文件已上传到: {audio_path}")
            return {
                "success": True,
                "message": "文件上传成功",
                "audio_path": audio_path,
                "subtitle_path": subtitle_path,
                "file_id": result.get("audio_file", {}).get("id")
            }
            
        except Exception as e:
            error_message = f"上传音频文件时出错: {e}"
            self._log(error_message, level="error")
            log_error(error_message)
            return {"success": False, "message": error_message}

    def _save_generated_video(self, file_path, source_videos, audio_path=None, 
                            combination_number=None, error_message=None):
        """Save generated video to database"""
        try:
            if not self.config:
                self._log("无法保存生成视频记录，配置不存在", level="warning")
                return None
                
            # Get file size and duration if file exists
            file_size = None
            duration = None
            if os.path.exists(file_path):
                file_size = os.path.getsize(file_path)
                
                # Try to get video duration
                try:
                    probe_cmd = [
                        "ffprobe", 
                        "-v", "error", 
                        "-show_entries", "format=duration", 
                        "-of", "csv=p=0", 
                        file_path
                    ]
                    import subprocess
                    duration_output = subprocess.check_output(
                        probe_cmd, 
                        startupinfo=Util.get_startupinfo()
                    ).decode().strip()
                    duration = float(duration_output) if duration_output else None
                except Exception as e:
                    self._log(f"获取视频时长失败: {e}", level="warning")
            
            # Determine status
            status = "completed" if not error_message else "failed"
            
            # Create database record
            video_record = self.dao_factory.get_generated_video_dao().create(
                config_id=self.config.id,
                file_path=file_path,
                filename=os.path.basename(file_path),
                output_folder=self.output_folder,
                source_videos=source_videos,
                audio_path=audio_path,
                combination_number=combination_number,
                file_size=file_size,
                duration=duration,
                status=status
            )
            
            if error_message and video_record:
                self.dao_factory.get_generated_video_dao().update_status(
                    video_id=video_record.id,
                    status="failed",
                    error_message=error_message
                )
                
            self._log(f"已保存生成视频记录，ID: {video_record.id}")
            return video_record.id
        except Exception as e:
            log_error(f"保存生成视频记录失败: {e}")
            self._log(f"保存生成视频记录失败: {e}", level="error")
            return None
        
        
    def process_merge_by_ids(self, prompt_data, output_folder, settings, date_range,
                        transition_effect, audio_ids=[], video_ids=[]):
        """
        根据提供的视频ID进行混搭
        
        :param prompt_data: 提示数据
        :param output_folder: 输出目录
        :param settings: 设置参数
        :param date_range: 日期范围
        :param transition_effect: 过渡效果
        :param audio_ids: 音频ID列表
        :param video_ids: 视频ID列表，每个包含id、category_order和category
        :return: 处理结果
        """
        if self.running:
            # 与process_merge类似，返回当前任务状态
            return {
                "success": True, 
                "resumed": True,
                "message": "已恢复正在运行的任务",
                "status": self.status,
                "logs": self.log_messages,
                "output_files": self.output_files,
                "params": {
                    "output_folder": self.output_folder,
                    "settings": self.settings,
                    "prompt_count": len(self.prompt_data) if hasattr(self, 'prompt_data') else 0,
                    "has_audio": len(self.audio_ids) > 0,
                    "transition_effect": self.transition_effect, 
                }
            }
        
        # 确保输出目录存在
        if not os.path.exists(output_folder):
            os.makedirs(output_folder, exist_ok=True)
            
        # 清空文件记录和日志
        self.output_files = []
        self.log_messages = []
        
        # 保存参数
        self.prompt_data = prompt_data
        self.output_folder = output_folder
        self.settings = settings
        self.date_range = date_range
        self.audio_ids = audio_ids
        self.transition_effect = transition_effect
        self.video_ids = video_ids
        
        # 保存配置到数据库
        try:
            self.config = self.dao_factory.get_video_generation_config_dao().create(
                name=f"Generation by IDs {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
                prompt_data=prompt_data,
                date_range=date_range,
                transition_effect=transition_effect,
                transition_duration=float(settings.get('transition_duration', 1.0)),
                remove_voice=settings.get('remove_voice', False),
                random_limit=settings.get('random_limit', 3),
                generate_all=settings.get('generate_all', False)
            )
            self._log(f"已保存生成配置，ID: {self.config.id}")
        except Exception as e:
            log_error(f"保存视频生成配置失败: {e}")
            self._log(f"保存视频生成配置失败: {e}", level="error")
            self.config = None
            
        # 开始异步处理
        self.running = True
        self.status = "running"
        
        self.thread = threading.Thread(target=self._process_by_video_ids)
        self.thread.daemon = True
        self.thread.start()
        
        return {"success": True, "message": "开始处理视频混搭(按ID)"}

    def _process_by_video_ids(self):
        """处理按视频ID合并的逻辑实现"""
        try:
            self._log("开始处理视频ID合成任务")
            
            # 按category_order对视频进行分组
            video_groups = {}
            video_paths_by_id = {}
            
            # 获取所有视频路径
            for video_item in self.video_ids:
                video_id = video_item.get('id')
                category_order = video_item.get('category_order')
                category = video_item.get('category')
                # 将视频按category_order分组
                if category_order not in video_groups:
                    video_groups[category_order] = []

                if category == '自定义':
                    video_groups[category_order].append(video_id)
                    continue

                # 通过VideoDAO获取视频路径
                video = self.dao_factory.get_video_dao().get_by_id(int(video_id))
                if not video or not video.local_path:
                    self._log(f"找不到视频ID: {video_id}", level="error")
                    continue
                    
                video_groups[category_order].append(video.local_path)
                video_paths_by_id[video_id] = video.local_path
                self._log(f"添加视频到组 {category_order}: ID={video_id}, 路径={video.local_path}")
            
            # 检查是否找到视频
            if not video_groups:
                self._log("没有找到任何有效视频", level="error")
                self.status = "completed"
                self.running = False
                return
            
            # 根据settings.generate_all决定处理方式
            if self.settings.get('generate_all', False):
                self._process_all_id_combinations(video_groups)
            else:
                self._process_single_id_combination(video_groups)
                
        except Exception as e:
            self._log(f"视频ID混搭过程中出错: {e}", level="error")
            log_error(f"视频ID混搭错误: {e}")
        finally:
            self.dao_factory.refresh_session()
            self.status = "completed"
            self.running = False

    def _process_single_id_combination(self, video_groups):
        """从每个分组中抽取一个视频生成一个合成视频"""
        
        try:
            # 按category_order排序，确保视频顺序正确
            ordered_groups = sorted(video_groups.keys())
            selected_videos = []
            
            # 从每个组中随机选择一个视频
            for order in ordered_groups:
                if not self.running:
                    break
                    
                if video_groups[order]:
                    # 随机选择一个视频
                    selected_video = random.choice(video_groups[order])
                    selected_videos.append(selected_video)
                    self._log(f"从组 {order} 中选择视频: {os.path.basename(selected_video)}")
                    
            if not selected_videos:
                self._log("没有足够的视频可供合并", level="warning")
                return
                
            # 创建输出文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            output_filename = f"merged_by_id_{timestamp}.mp4"
            output_path = os.path.join(self.output_folder, output_filename)
            
            # 合并视频
            self._log(f"开始合并 {len(selected_videos)} 个视频...")
            remove_voice = self.settings.get('remove_voice', False)
            
            # 调用合并功能
            merged_videos = Util.merge_videos(
                *selected_videos,
                output_path=output_path,
                remove_voice=remove_voice,
                audio_ids=self.audio_ids,
                logger=self._log,
                transition_effect=self.transition_effect
            )
            
            # 处理结果
            for merged_video in merged_videos:
                audio_path = merged_video.get("audio", "")
                video = merged_video.get("video", "")
                self.output_files.append({
                    "output_path": video,
                    "type": "video",
                    "name": os.path.basename(video),
                    "audio_name": os.path.basename(audio_path) if audio_path else "",
                })
                
                # 保存到数据库
                self._save_generated_video(
                    file_path=video,
                    source_videos=selected_videos,
                    audio_path=audio_path,
                )
                self._log(f"合并完成: {os.path.basename(video)}")
        except Exception as e:
            self._log(f"单一组合视频合成失败: {e}", level="error")

    def _process_all_id_combinations(self, video_groups):
        """生成所有可能的组合视频"""
        
        try:
            # 按category_order排序，确保视频顺序正确
            ordered_groups = sorted(video_groups.keys())
            group_videos = [video_groups[order] for order in ordered_groups if order in video_groups]
            
            # 确保有足够的分组
            if len(group_videos) < 1:
                self._log("没有足够的视频组进行组合", level="warning")
                return
                
            # 生成所有可能的组合
            combinations = list(itertools.product(*group_videos))
            self._log(f"共生成 {len(combinations)} 种组合可能")
            
            # 处理所有组合
            for i, combo in enumerate(combinations):
                if not self.running:
                    break
                    
                # 检查是否有重复视频
                if len(set(combo)) != len(combo):
                    self._log(f"跳过组合 {i+1}，因为包含重复视频")
                    continue
                    
                self._log(f"处理组合 {i+1}/{len(combinations)}")
                
                # 创建输出文件名
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                output_filename = f"combo_id_{i+1}_{timestamp}.mp4"
                output_path = os.path.join(self.output_folder, output_filename)
                
                # 合并视频
                self._log(f"开始合并 {len(combo)} 个视频...")
                remove_voice = self.settings.get('remove_voice', False)
                
                try:
                    merged_videos = Util.merge_videos(
                        *combo,
                        output_path=output_path,
                        remove_voice=remove_voice,
                        audio_ids=self.audio_ids,
                        logger=self._log,
                        transition_effect=self.transition_effect
                    )
                    
                    for merged_video in merged_videos:
                        audio_path = merged_video.get("audio", "")
                        video = merged_video.get("video", "")
                        self.output_files.append({
                            "output_path": video,
                            "type": "video",
                            "name": os.path.basename(video),
                            "audio_name": os.path.basename(audio_path) if audio_path else "",
                        })
                        
                        # 保存到数据库
                        self._save_generated_video(
                            file_path=video,
                            source_videos=list(combo),
                            audio_path=audio_path,
                            combination_number=i + 1
                        )
                        self._log(f"合并完成: {os.path.basename(video)}")
                except Exception as e:
                    self._log(f"组合 {i+1} 视频混搭失败: {e}", level="error")
                    
            self._log("所有组合处理完成")
        except Exception as e:
            self._log(f"组合视频处理失败: {e}", level="error")
            
            
    def add_opening_ending_to_video(self, video_path, output_folder=None, opening_file_id=None, ending_file_id=None, transition_effect="fade"):
        """
        为视频添加片头片尾
        
        :param video_path: 要处理的视频文件路径
        :param output_folder: 输出目录，不指定则使用默认目录
        :param opening_file_id: 自定义片头视频的文件ID，不指定则使用默认片头
        :param ending_file_id: 自定义片尾视频的文件ID，不指定则使用默认片尾
        :param transition_effect: 过渡效果，默认为淡入淡出
        :return: 处理结果
        """
        try:
            if not os.path.exists(video_path):
                return {"success": False, "message": "视频文件不存在"}
                
            # 设置输出目录
            if not output_folder:
                from src.config import OUTPUT_DIR
                output_folder = OUTPUT_DIR
                
            if not os.path.exists(output_folder):
                os.makedirs(output_folder, exist_ok=True)
                
            # 获取片头视频
            opening_video = None
            if opening_file_id:
                # 从数据库获取自定义片头
                file = self.dao_factory.get_uploaded_file_dao().get_by_id(opening_file_id)
                if file and file.file_path and os.path.exists(file.file_path):
                    # 检查meta_data.video_type是否为opening
                    if file.meta_data and file.meta_data.get('video_type') == 'opening':
                        opening_video = file.file_path
                        self._log(f"使用自定义片头: {os.path.basename(opening_video)}")
                    else:
                        self._log("指定的文件不是片头视频", level="warning")
                else:
                    self._log("指定的片头文件不存在", level="warning")
            
            if not opening_video:
                # 使用默认片头
                from src.config import STATIC_DIR
                default_opening = os.path.join(STATIC_DIR, "default_opening.mp4")
                if os.path.exists(default_opening):
                    opening_video = default_opening
                    self._log(f"使用默认片头")
                    
            # 获取片尾视频
            ending_video = None
            if ending_file_id:
                # 从数据库获取自定义片尾
                file = self.dao_factory.get_uploaded_file_dao().get_by_id(ending_file_id)
                if file and file.file_path and os.path.exists(file.file_path):
                    # 检查meta_data.video_type是否为ending
                    if file.meta_data and file.meta_data.get('video_type') == 'ending':
                        ending_video = file.file_path
                        self._log(f"使用自定义片尾: {os.path.basename(ending_video)}")
                    else:
                        self._log("指定的文件不是片尾视频", level="warning")
                else:
                    self._log("指定的片尾文件不存在", level="warning")
                    
            if not ending_video:
                # 使用默认片尾
                from src.config import STATIC_DIR
                default_ending = os.path.join(STATIC_DIR, "default_ending.mp4")
                if os.path.exists(default_ending):
                    ending_video = default_ending
                    self._log(f"使用默认片尾")
            
            # 准备合并的视频序列
            videos_to_merge = []
            if opening_video:
                videos_to_merge.append(opening_video)
                
            videos_to_merge.append(video_path)
            
            if ending_video:
                videos_to_merge.append(ending_video)
                
            if len(videos_to_merge) <= 1:
                return {"success": False, "message": "没有片头或片尾可添加"}
                
            # 创建输出文件名
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            video_basename = os.path.basename(video_path)
            video_name, video_ext = os.path.splitext(video_basename)
            output_filename = f"{video_name}_with_intro_outro_{timestamp}{video_ext}"
            output_path = os.path.join(output_folder, output_filename)
            
            # 合并视频
            self._log(f"开始添加片头片尾，共 {len(videos_to_merge)} 个视频片段...")
            merged_videos = Util.merge_videos(
                *videos_to_merge,
                output_path=output_path,
                remove_voice=False,  # 保留原始音频
                logger=self._log,
                transition_effect=transition_effect
            )
            
            # 处理结果
            result_videos = []
            for merged_video in merged_videos:
                video = merged_video.get("video", "")
                if video:
                    result_videos.append({
                        "output_path": video,
                        "name": os.path.basename(video),
                    })
                    self._log(f"处理完成: {os.path.basename(video)}")
                    
            return {
                "success": True,
                "message": "成功添加片头片尾",
                "videos": result_videos
            }
            
        except Exception as e:
            error_message = f"添加片头片尾时出错: {e}"
            self._log(error_message, level="error")
            log_error(error_message)
            return {"success": False, "message": error_message}
        
    def add_opening_ending_to_video_by_id(self, video_id, output_folder=None, opening_file_id=None, ending_file_id=None, transition_effect="fade"):
        """
        根据视频ID为视频添加片头片尾
        
        :param video_id: 要处理的视频ID
        :param output_folder: 输出目录，不指定则使用默认目录
        :param opening_file_id: 自定义片头视频的文件ID，不指定则使用默认片头
        :param ending_file_id: 自定义片尾视频的文件ID，不指定则使用默认片尾
        :param transition_effect: 过渡效果，默认为淡入淡出
        :return: 处理结果
        """
        # 获取视频路径
        video = self.dao_factory.get_video_dao().get_by_id(int(video_id))
        if not video or not video.local_path or not os.path.exists(video.local_path):
            return {"success": False, "message": f"找不到视频ID: {video_id}或视频文件不存在"}
            
        # 调用主方法处理
        return self.add_opening_ending_to_video(
            video_path=video.local_path,
            output_folder=output_folder,
            opening_file_id=opening_file_id,
            ending_file_id=ending_file_id,
            transition_effect=transition_effect
        )
        
    def process_folder_add_intro_outro(self, folder_path, output_folder=None, opening_file_id=None, ending_file_id=None, transition_effect="fade"):
        """
        批量处理文件夹中的视频，为每个视频添加片头片尾
        
        :param folder_path: 要处理的文件夹路径
        :param output_folder: 输出目录，不指定则使用默认目录
        :param opening_file_id: 自定义片头视频的文件ID，不指定则使用默认片头
        :param ending_file_id: 自定义片尾视频的文件ID，不指定则使用默认片尾
        :param transition_effect: 过渡效果，默认为淡入淡出
        :return: 处理结果
        """
        try:
            if not os.path.exists(folder_path) or not os.path.isdir(folder_path):
                return {"success": False, "message": "指定的文件夹不存在或不是一个目录"}
                
            # 设置输出目录
            if not output_folder:
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                output_folder = os.path.join(folder_path, f"processed_{timestamp}")
                
            if not os.path.exists(output_folder):
                os.makedirs(output_folder, exist_ok=True)
                
            # 获取所有视频文件
            video_files = []
            for filename in os.listdir(folder_path):
                file_path = os.path.join(folder_path, filename)
                if os.path.isfile(file_path) and filename.lower().endswith(('.mp4', '.mov', '.avi', '.mkv')):
                    video_files.append(file_path)
                    
            if not video_files:
                return {"success": False, "message": "文件夹中没有找到视频文件"}
                
            # 处理每个视频
            processed_videos = []
            failed_videos = []
            
            for video_path in video_files:
                result = self.add_opening_ending_to_video(
                    video_path=video_path,
                    output_folder=output_folder,
                    opening_file_id=opening_file_id,
                    ending_file_id=ending_file_id,
                    transition_effect=transition_effect
                )
                
                if result["success"]:
                    processed_videos.extend(result["videos"])
                else:
                    failed_videos.append({
                        "path": video_path,
                        "name": os.path.basename(video_path),
                        "error": result["message"]
                    })
                    
            return {
                "success": True,
                "message": f"处理完成，成功: {len(processed_videos)}，失败: {len(failed_videos)}",
                "processed_videos": processed_videos,
                "failed_videos": failed_videos,
                "output_folder": output_folder
            }
            
        except Exception as e:
            self.dao_factory.close_session()
            error_message = f"批量处理视频添加片头片尾时出错: {e}"
            self._log(error_message, level="error")
            log_error(error_message)
            return {"success": False, "message": error_message}